创建第一个 ROS2 功能包
ROS2 功能包
功能包是 ROS2 代码的组织单元。如果想构建代码或与他人共享,那么需要将代码组织在一个功能包中。通过功能包,用户可以发布 ROS2 成果。
ROS2 使用 ament 作为功能包的构建系统,使用 colcon 作为其构建工具。用户可以使用CMake 或 Python 创建一个功能包,这些都是官方支持的。
ROS2 Python 和 CMake 功能包各自有其最低要求的内容:
CMake功能包内容
-
CMakeLists.txt文件,描述如何构建功能包内的代码 -
include/<package_name>目录,包含功能包的公共头文件 -
package.xml文件,包含有关功能包的元信息 -
src目录,包含功能包的源代码
python功能包内容
-
package.xml文件:包含有关功能包的元信息。 -
resource/<package_name>标记文件:用于标记功能包,使ROS 2工具能够识别。 -
setup.cfg文件:当功能包包含可执行文件时必需,以便ros2 run可以找到它们。 -
setup.py文件:包含安装功能包的指令。 -
<package_name>目录:与功能包同名的目录,用于ROS 2工具查找功能包,包含__init__.py文件。
最简单的功能包的文件结构可能如下所示:
my_package/
CMakeLists.txt
include/my_package/
package.xml
src/
my_package/
package.xml
resource/my_package
setup.cfg
setup.py
my_package/
创建并构建功能包
单个工作空间可以包含任意数量的功能包,每个功能包都有自己的文件夹。用户也可以在同一个工作空间中拥有不同构建类型的功能包(CMake、Python等),但不能有嵌套功能包。
一个简单的工作空间可能如下所示:
ros2_ws/
src/
cpp_package_1/
CMakeLists.txt
include/cpp_package_1/
package.xml
src/
py_package_1/
package.xml
resource/py_package_1
setup.cfg
setup.py
py_package_1/
...
cpp_package_n/
CMakeLists.txt
include/cpp_package_n/
package.xml
src/
创建功能包
首先,加载ros底层环境。
source /opt/ros/jazzy/setup.bash
在创建的工作空间 ros2_ws 来创建新功能包。确保现在位于 src 文件夹中,在 ROS2中创建新功能包的命令语法是:
ros2 pkg create --build-type ament_cmake <package_name>
ros2 pkg create --build-type ament_python <package_name>
在终端中输入以下命令:
ros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name my_node my_package_cpp
ros2 pkg create --build-type ament_python --license Apache-2.0 --node-name my_node my_package_py
--node-name 和 --license 为可选参数,--node-name 选项在功能包中创建一个简单的 Hello World 类型的可执行文件,--license 声明功能包的许可信息。现在,工作空间的 src 目录中新建一个名为 my_package 的新文件夹。
运行命令后,该终端将返回创建的具体文件的名称。
构建功能包
返回到工作空间的根目录:
cd ~/ros2_ws
使用如下命令构建工作空间的所有功能包:
colcon build
当工作空间中只有几个功能包时,使用该命令没有问题。但是当有许多功能包时,colcon build 可能需要很长时间。如果只构建 my_package 功能包,可以运行:
colcon build --packages-select my_package_cpp
加载工作空间并使用
要运行新功能包和可执行文件,首先打开一个新的终端并加载主要ROS 2安装。
然后,在 ros2_ws 目录内,运行以下命令来加载工作空间:
source install/local_setup.bash
现在工作空间已被添加到路径中,现在可以使用新功能包中的可执行文件。
要运行功能包创建期间使用--node-name 参数创建的可执行文件,输入命令:
ros2 run my_package_cpp my_node
将在终端返回消息:
hello world my_package package
查看功能包内容
在 ros2_ws/src/my_package_cpp 内,我们将看到 ros2 pkg create 自动生成的文件和文件夹:
CMakeLists.txt include package.xml src
my_node.cpp 位于 src 目录内,存放所有自定义C++节点源文件。
my_package package.xml resource setup.cfg setup.py test
my_node.py 位于 my_package_py 目录内, 存放所有自定义python节点源文件。
自定义package.xml
在功能包创建成功后,会在终端返回提示消息,其中 description 和 license 字段包含 TODO 注释。 这是因为功能包描述和许可声明不是自动设置的,在发布功能包之前需要填写这些信息。
在ros2_ws/src/my_package_cpp打开package.xml文件:
<?xml version="1.0"?>
<?xml-model
href="http://download.ros.org/schema/package_format3.xsd"
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_package</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="user@todo.todo">user</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
在ros2_ws/src/my_package_py打开package.xml文件:
<?xml version="1.0"?>
<?xml-model
href="http://download.ros.org/schema/package_format3.xsd"
schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>my_package</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="user@todo.todo">user</maintainer>
<license>TODO: License declaration</license>
<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
<test_depend>ament_pep257</test_depend>
<test_depend>python3-pytest</test_depend>
<export>
<build_type>ament_python</build_type>
</export>
</package>
在maintainer行上输入姓名和电子邮件, 编辑description行总结功能包:
<description>Beginner client libraries tutorials practice package</description>
然后,更新 license 行 <license>Apache License 2.0</license>。 这些信息的填写并不对程序运行产生影响。编辑完成后,记得保存。
在license标签下方,会有一些以 _depend 结尾的标签名。 这是 package.xml 列出了对其他功能包的依赖项,供colcon搜索。 my_package_cpp 和 my_package_py 很简单,没有任何依赖项。对于 CMake 形式的功能包到此结束。如果使用 python 还有setup.py 的配置。
setup.py 文件包含与 package.xml 具有相同的描述、维护者和许可证字段,因此用户也需要设置这些字段,这些信息在两个文件中必须完全匹配。版本和名称(package_name)也需要完全匹配,并且应该在两个文件中自动填充。
编辑setup.py 文件
使用文本编辑器打开 setup.py 文件。
from setuptools import find_packages, setup
package_name = 'my_py_pkg'
setup(
name=package_name,
version='0.0.0',
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'],
zip_safe=True,
maintainer='TODO',
maintainer_email='TODO',
description='TODO: Package description',
license='TODO: License declaration',
tests_require=['pytest'],
entry_points={
'console_scripts': [
'my_node = my_py_pkg.my_node:main'
],
},
)
编辑 maintainer, maintainer_email, 和 description 匹配 package.xml 内容。
本章小结
本章介绍了 ROS2 工作空间和功能包的基本概念与使用方法,讲解了底层环境与覆盖环境的关系,以及工作空间的创建、构建和加载流程。通过 colcon 构建工具,读者了解了 ROS 2 工程的基本目录结构及其作用。
同时,本章说明了 C++ 与 Python 功能包的基本结构和创建方式,并简要介绍了功能包元信息文件的配置要点。通过实践示例,读者能够完成从创建功能包到运行节点的完整流程,为后续 ROS 2 编程学习奠定基础。